package org.ns.learn.rpc.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.ns.learn.rpc.codec.*;

public class RpcClient {

    private NioEventLoopGroup eventExecutors = new NioEventLoopGroup(1);
    private Bootstrap b;
    private Channel channel;
    private MessageManage messageManage = new MessageManage();
    private String host;
    private int port;
    public RpcClient(String host, int port) throws RpcClientException{
        this.host = host;
        this.port = port;
        try {
            b = new Bootstrap();
            b.group(eventExecutors);
            b.channel(NioSocketChannel.class);
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline p = ch.pipeline();
                    p.addLast(new RpcMessageRequestEncode());
                    p.addLast(new RpcMessageResponseDecode());
                    p.addLast(new RpcClientHandler(RpcClient.this, messageManage));
                }
            });

            ChannelFuture channelFuture = b.connect(host, port).sync();
            channel = channelFuture.channel();
        } catch (Exception e) {

            throw new RpcClientException("客户端开启失败", e);
        }
    }

    public RpcClientResponse send(RpcRequest request) throws RpcRequestTimeouException{
       return messageManage.send(channel, request);
    }

    public void close() {
        channel.close();
        eventExecutors.shutdownGracefully();
    }

    @Override
    public String toString() {
        return host + ":" + port;
    }

    public String getName() {
        return host + ":" + port;
    }

    public static void main(String[] args) throws Exception{

        RpcClient rpcClient = new RpcClient("127.0.0.1", 11111);
        try {
            RpcRequest request = new RpcRequest("userService", "getNickName", new ParameterType(long.class, null), 1000L);
            Thread.sleep(1000);
            RpcResponse response = rpcClient.send(request);
            response.throwException();
            System.out.println(response.getResult());
        } finally {

            rpcClient.close();
        }
    }
}
